
package com.tfq.cloud.auth.controller


import com.tfq.cloud.model.auth.Account
import org.pac4j.jwt.profile.JwtGenerator
import org.pac4j.jwt.profile.JwtProfile
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.*
import reactor.core.publisher.Mono
import java.util.*

@RestController
@RequestMapping("/auth")
 class AuthController {
   @Autowired
   val  jwtGenerator: JwtGenerator?=null
    @PostMapping("/login")
    fun login(@RequestBody account: Account): Mono<String> {
        val worker = SnowflakeIdWorker(1, 1)
        val now=Date()
        val jwtProfile =  JwtProfile()

        jwtProfile.clientName=account.username
        jwtProfile.id=account.id
        jwtProfile.attributes["jti"] = worker.nextId().toString() //设置jwtProfile.jwtId
        jwtProfile.attributes["aud"] = listOf("")//设置jwtProfile.audience
        jwtProfile.attributes["iss"] = listOf("")//设置jwtProfile.issuer
        jwtProfile.attributes["nbf"] = now //设置jwtProfile.notBefore
        jwtProfile.attributes["iat"] = now //设置jwtProfile.issuedAt
        jwtProfile.attributes["exp"] = Date(now.time+3600000) //设置jwtProfile.expirationDate
        jwtProfile.roles=setOf("")
        jwtProfile.authenticationAttributes[""]=""

        jwtGenerator!!.generate(JwtProfile())
        return Mono.justOrEmpty("")
    }
    @GetMapping("/test")
    fun test(): Mono<String> {
      val jwtProfile =  JwtProfile()
        jwtGenerator!!.generate(JwtProfile())
        return Mono.justOrEmpty("")
    }

}
class SnowflakeIdWorker(datacenterId: Long, workerId: Long, sequence: Long = 0) {

    private val twepoch = 1288834974657L

    private val workerIdBits = 5
    private val datacenterIdBits = 5
    private val maxWorkerId = -1L xor (-1L shl workerIdBits)
    private val maxDatacenterId = -1L xor (-1L shl datacenterIdBits)
    private val sequenceBits = 12

    private val workerIdShift = sequenceBits
    private val datacenterIdShift = sequenceBits + workerIdBits
    private val timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits
    private val sequenceMask = -1L xor (-1L shl sequenceBits)

    private var workerId: Long = 0
    private var datacenterId: Long = 0
    private var sequence: Long = 0

    private var lastTimestamp = -1L

    init {
        require(workerId <= maxWorkerId) { "worker Id can't be greater than $maxWorkerId or less than 0" }
        require(datacenterId <= maxDatacenterId) { "datacenter Id can't be greater than $maxDatacenterId or less than 0" }
        this.workerId = workerId
        this.datacenterId = datacenterId
        this.sequence = sequence
    }

    @Synchronized
    fun nextId(): Long {
        var timestamp = timeGen()

        if (timestamp < lastTimestamp) {
            throw RuntimeException(
                String.format(
                    "Clock moved backwards.  Refusing to generate id for %d milliseconds",
                    lastTimestamp - timestamp
                )
            )
        }

        if (lastTimestamp == timestamp) {
            sequence = (sequence + 1) and sequenceMask
            if (sequence == 0L) {
                timestamp = tilNextMillis(lastTimestamp)
            }
        } else {
            sequence = 0L
        }

        lastTimestamp = timestamp

        return (timestamp - twepoch shl timestampLeftShift) or
                (datacenterId shl datacenterIdShift) or
                (workerId shl workerIdShift) or
                sequence
    }

    protected fun tilNextMillis(lastTimestamp: Long): Long {
        var timestamp = timeGen()
        while (timestamp <= lastTimestamp) {
            timestamp = timeGen()
        }
        return timestamp
    }

    protected fun timeGen(): Long {
        return System.currentTimeMillis()
    }
}
